package com.example.qrcode.service.impl;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.example.qrcode.entity.CurrentData;
import com.example.qrcode.entity.SceneBindingAi;
import com.example.qrcode.entity.SceneBindingDi;
import com.example.qrcode.mapper.CurrentDataMapper;
import com.example.qrcode.mapper.ProductMapper;
import com.example.qrcode.mapper.SceneBindingAiMapper;
import com.example.qrcode.mapper.SceneBindingDiMapper;
import com.example.qrcode.service.DataBindingService;
import com.example.qrcode.vo.SceneBindingAiDataVO;
import com.example.qrcode.vo.SceneBindingDiDataVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import com.alibaba.fastjson2.JSONObject;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class DataBindingServiceImpl implements DataBindingService {

    private final ProductMapper productMapper;
    private final CurrentDataMapper currentDataMapper;
    private final SceneBindingAiMapper sceneBindingAiMapper;
    private final SceneBindingDiMapper sceneBindingDiMapper;

    private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Override
    public List<SceneBindingAiDataVO> getSceneBindingAiData(String productSNo) {
        try {
            // 1. 根据产品序列号获取设备ID和出线数量
            String deviceId = productMapper.getDeviceIdByProductSNo(productSNo);
            Integer lineNum = productMapper.getLineNumByProductSNo(productSNo);
            
            if (StringUtils.isBlank(deviceId)) {
                log.warn("未找到产品序列号对应设备ID: {}", productSNo);
                return new ArrayList<>();
            }

            // 2. 根据设备ID获取AI数据配置（先查设备专属，再查8出线通用配置）
            List<SceneBindingAi> aiConfigList = sceneBindingAiMapper.getSceneBindingAiByDeviceCode(deviceId);
            if (aiConfigList == null || aiConfigList.isEmpty()) {
                // 如果设备专属配置为空，统一使用8出线的配置
                aiConfigList = sceneBindingAiMapper.getSceneBindingAiBySceneId(8);
                if (aiConfigList != null && !aiConfigList.isEmpty()) {
                    log.info("设备{}未配置AI数据绑定，使用8出线通用配置成功", deviceId);
                } else {
                    // 如果8出线配置查找失败，尝试根据graphic_name查找（兼容旧逻辑）
                    String graphicName = "8出线M";
                    aiConfigList = sceneBindingAiMapper.getSceneBindingAiByGraphicName(graphicName);
                    if (aiConfigList != null && !aiConfigList.isEmpty()) {
                        log.info("设备{}未配置AI数据绑定，使用8出线通用配置成功", deviceId);
                    }
                }
            }
            
            if (aiConfigList == null || aiConfigList.isEmpty()) {
                log.info("设备{}及8出线通用配置均未配置AI数据绑定", deviceId);
                return new ArrayList<>();
            }

            // 3. 获取设备实时数据
            List<CurrentData> currentDataList = currentDataMapper.getCurrentDataByDeviceId(deviceId);
            CurrentData analogsData = null;
            for (CurrentData data : currentDataList) {
                if ("analog".equals(data.getServiceId())) {
                    analogsData = data;
                    break;
                }
            }

            if (analogsData == null || StringUtils.isBlank(analogsData.getBodyData())) {
                log.warn("设备{}未找到模拟量实时数据", deviceId);
                return new ArrayList<>();
            }

            // 4. 解析实时数据
            JSONObject jsonData = JSONObject.parseObject(analogsData.getBodyData());

            // 5. 合并配置和实时数据
            List<SceneBindingAiDataVO> result = new ArrayList<>();
            for (SceneBindingAi config : aiConfigList) {
                // 只处理设备实际出线数量范围内的点位
                if (jsonData.containsKey(config.getModelPointsId()) && isPointInLineRange(config.getModelPointsId(), lineNum)) {
                    SceneBindingAiDataVO vo = new SceneBindingAiDataVO();
                    // 复制配置信息
                    vo.setId(config.getId());
                    vo.setSceneId(config.getSceneId());
                    vo.setDeviceCode(config.getDeviceCode());
                    vo.setSvgId(config.getSvgId());
                    vo.setModelPointsId(config.getModelPointsId());
                    vo.setDefaultValue(config.getDefaultValue());
                    vo.setColor(config.getColor());
                    vo.setDescription(config.getDescription());
                    vo.setDataType(config.getDataType());
                    vo.setPrecision(config.getPrecision());

                    // 设置实时数据
                    vo.setCurrentValue(jsonData.getString(config.getModelPointsId()));
                    if (analogsData.getUpdateTime() != null) {
                        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                        vo.setUpdateTime(analogsData.getUpdateTime().format(formatter));
                    }

                    // 设置设备和点位名称（可以根据需要添加映射逻辑）
                    vo.setDeviceName("设备名称"); // TODO: 根据需要添加设备名称映射
                    vo.setModelPointName("点位名称"); // TODO: 根据需要添加点位名称映射

                    result.add(vo);
                }
            }

            return result;
        } catch (Exception e) {
            log.error("获取AI数据绑定信息失败, productSNo: {}", productSNo, e);
            return new ArrayList<>();
        }
    }



    @Override
    public List<SceneBindingDiDataVO> getSceneBindingDiData(String productSNo) {
        try {
            // 1. 根据产品序列号获取设备ID和出线数量
            String deviceId = productMapper.getDeviceIdByProductSNo(productSNo);
            Integer lineNum = productMapper.getLineNumByProductSNo(productSNo);
            
            if (StringUtils.isBlank(deviceId)) {
                log.warn("未找到产品序列号对应设备ID: {}", productSNo);
                return new ArrayList<>();
            }

            // 2. 根据设备ID获取DI数据配置（先查设备专属，再查8出线通用配置）
            List<SceneBindingDi> diConfigList = sceneBindingDiMapper.getSceneBindingDiByDeviceCode(deviceId);
            if (diConfigList == null || diConfigList.isEmpty()) {
                // 如果设备专属配置为空，统一使用8出线的配置
                diConfigList = sceneBindingDiMapper.getSceneBindingDiBySceneId(8);
                if (diConfigList != null && !diConfigList.isEmpty()) {
                    log.info("设备{}未配置DI数据绑定，使用8出线通用配置成功", deviceId);
                } else {
                    // 如果8出线配置查找失败，尝试根据graphic_name查找（兼容旧逻辑）
                    String graphicName = "8出线M";
                    diConfigList = sceneBindingDiMapper.getSceneBindingDiByGraphicName(graphicName);
                    if (diConfigList != null && !diConfigList.isEmpty()) {
                        log.info("设备{}未配置DI数据绑定，使用8出线通用配置成功", deviceId);
                    }
                }
            }
            
            if (diConfigList == null || diConfigList.isEmpty()) {
                log.info("设备{}及8出线通用配置均未配置DI数据绑定", deviceId);
                return new ArrayList<>();
            }

            // 3. 获取设备实时数据
            List<CurrentData> currentDataList = currentDataMapper.getCurrentDataByDeviceId(deviceId);
            CurrentData discreteData = null;
            for (CurrentData data : currentDataList) {
                if ("discrete".equals(data.getServiceId())) {
                    discreteData = data;
                    break;
                }
            }

            if (discreteData == null || StringUtils.isBlank(discreteData.getBodyData())) {
                log.warn("设备{}未找到开关量实时数据", deviceId);
                return new ArrayList<>();
            }

            // 4. 解析实时数据
            JSONObject jsonData = JSONObject.parseObject(discreteData.getBodyData());

            // 5. 合并配置和实时数据
            List<SceneBindingDiDataVO> result = new ArrayList<>();
            for (SceneBindingDi config : diConfigList) {
                // 只处理设备实际出线数量范围内的点位
                if (jsonData.containsKey(config.getModelPointsId()) && isPointInLineRange(config.getModelPointsId(), lineNum)) {
                    SceneBindingDiDataVO vo = new SceneBindingDiDataVO();
                    // 复制配置信息 - 根据正确的实体类修改
                    vo.setId(config.getId());
                    vo.setSceneId(config.getSceneId());           // 修改：deviceGroupId -> sceneId
                    vo.setDeviceCode(config.getDeviceCode());     // 修改：使用配置中的deviceCode
                    vo.setSvgId(config.getSvgId());
                    vo.setModelPointsId(config.getModelPointsId());
                    vo.setDefaultValue(config.getDefaultValue());
                    vo.setColor(config.getColor());
                    vo.setDescription(config.getDescription());
                    vo.setValue0(config.getValue0());             // 修改：value0
                    vo.setValue1(config.getValue1());             // 修改：value1
                    vo.setRenderType(config.getRenderType());

                    // 设置实时数据
                    vo.setCurrentValue(jsonData.getString(config.getModelPointsId()));
                    if (discreteData.getUpdateTime() != null) {
                        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                        vo.setUpdateTime(discreteData.getUpdateTime().format(formatter));
                    }

                    // 设置设备和点位名称（可以根据需要添加映射逻辑）
                    vo.setDeviceName("设备名称"); // TODO: 根据需要添加设备名称映射
                    vo.setModelPointName("点位名称"); // TODO: 根据需要添加点位名称映射

                    result.add(vo);
                }
            }

            return result;
        } catch (Exception e) {
            log.error("获取DI数据绑定信息失败, productSNo: {}", productSNo, e);
            return new ArrayList<>();
        }
    }

    /**
     * 判断点位是否在指定出线数量范围内
     * @param modelPointsId 点位ID，如 K01_P, K02_Ia, J01_Ua 等
     * @param lineNum 实际出线数量
     * @return true表示在范围内，false表示超出范围
     */
    private boolean isPointInLineRange(String modelPointsId, Integer lineNum) {
        if (lineNum == null || lineNum <= 0) {
            return false;
        }
        
        // 进线点位（J01_*）始终在范围内
        if (modelPointsId.startsWith("J01_")) {
            return true;
        }
        
        // 出线点位（K01_*, K02_*, ...）需要检查出线编号
        if (modelPointsId.startsWith("K")) {
            try {
                // 提取出线编号，如 K01_P -> 01 -> 1
                String lineNumberStr = modelPointsId.substring(1, 3);
                int lineNumber = Integer.parseInt(lineNumberStr);
                return lineNumber <= lineNum;
            } catch (NumberFormatException e) {
                // 如果解析失败，默认不在范围内
                return false;
            }
        }
        
        // 其他点位默认在范围内
        return true;
    }
}

